home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / comm / bbs / Hydra11s.lha / HBBS / Source / Node / Node_Input.c < prev    next >
C/C++ Source or Header  |  1996-08-05  |  63KB  |  2,218 lines

  1. /*
  2.  
  3.   todo:
  4.  
  5.   * add history to Get_Line()
  6.   * add timeout to RunDoor()
  7.  
  8.   done:
  9.  
  10.   moved N_ND->DoorReturn[0]=0; from godoor() to systemdoor() and userdoor()
  11.   in case a door was supposed to run, but was not setup in the commands
  12.   files yet..
  13.  
  14.   moved N_ND->ActiveDoor=NULL; from rundoor to godoor() as CLI doors would
  15.   then cause the node to think the door had crashed :-)
  16.  
  17.  
  18. */
  19.  
  20. #define USE_BUILTIN_MATH
  21. #include <string.h>
  22. #include <math.h>
  23. #include <stdio.h>
  24. #include <exec/types.h>
  25. #include <libraries/locale.h>
  26. #include <exec/memory.h>
  27. #include <dos/dosextens.h>
  28. #include <intuition/screens.h>
  29. #include <intuition/intuition.h>
  30. #include <intuition/gadgetclass.h>
  31. #include <libraries/gadtools.h>
  32. #include <diskfont/diskfont.h>
  33. #include <utility/utility.h>
  34. #include <graphics/gfxbase.h>
  35. #include <devices/console.h>
  36. #include <workbench/workbench.h>
  37. #include <graphics/scale.h>
  38. #include <clib/locale_protos.h>
  39. #include <clib/exec_protos.h>
  40. #include <clib/wb_protos.h>
  41. #include <clib/intuition_protos.h>
  42. #include <clib/gadtools_protos.h>
  43. #include <clib/graphics_protos.h>
  44. #include <clib/utility_protos.h>
  45. #include <clib/diskfont_protos.h>
  46.  
  47. #include <dos/dos.h>
  48. #include <dos/dostags.h>
  49. #include <stdlib.h>
  50. #include <stdio.h>
  51. #include <ctype.h>
  52. #include <time.h>
  53. #include <libraries/reqtools.h>
  54.  
  55. #include <clib/alib_protos.h>
  56. #include <clib/dos_protos.h>
  57. #include <clib/reqtools_protos.h>
  58.  
  59. #include "NodeGUI.h"
  60.  
  61. #define ClrSignal(s)  SetSignal(0,s)
  62.  
  63. extern struct ReqToolsBase *ReqToolsBase;
  64. extern ULONG InfoWinActive;
  65. extern ULONG *rttags;
  66.  
  67. #include "/common/types.h"
  68. #include "/common/errors.h"
  69. #include "/common/defines.h"
  70. #include "/common/structures.h"
  71. #include "/common/strings.h"
  72. #include "/common/files.h"
  73. #include "/common/ansi_codes.h"
  74.  
  75. #include "Node_Console_Protos.h"
  76. #include "Node_Serial_Protos.h"
  77. #include "Node_Main_Protos.h"
  78. #include "Node_Misc_Protos.h"
  79. #include "Node_Input_Protos.h"
  80. #include "/library/hbbscommon_protos.h"
  81. #include "/library/hbbscommon_pragmas.h"
  82. #include "nodelibrary/hbbsnode_protos.h"
  83. #include "nodelibrary/hbbsnode_pragmas.h"
  84.  
  85. extern int N_NodeNum;
  86. extern struct BBSGlobalData *BBSGlobal;
  87. extern struct NodeData *N_ND;
  88. extern struct Library *HBBSCommonBase;
  89. extern struct Library *HBBSNodeBase;
  90. extern struct List *HistoryList;
  91. extern ULONG HistoryItems;
  92.  
  93. #include "/common/shared_protos.h"
  94.  
  95. void SetUpSigs( void )
  96. {
  97.   // this routine sets up all the signals availiable so you can checksignal() them
  98.   // or wait() on them or whatever....
  99.  
  100.  
  101.   if (N_ND->NodeSettings.Iconified==FALSE)
  102.     N_ND->WinSig=DEF_WINSIG;
  103.   else
  104.     N_ND->WinSig=0L;
  105.  
  106.   if (N_ND->InformationOpen)
  107.     N_ND->InfoWinSig=DEF_INFOWINSIG;
  108.   else
  109.     N_ND->InfoWinSig=0L;
  110.  
  111.   if (N_ND->SettingsOpen)
  112.     N_ND->SettingsWinSig=DEF_SETTINGSWINSIG;
  113.   else
  114.     N_ND->SettingsWinSig=0L;
  115.  
  116.   SetupConSerSigs();
  117.  
  118.   N_ND->PortSig=DEF_PORTSIG;
  119.   N_ND->TimerSig=DEF_TIMERSIG;
  120. }
  121.  
  122. void SetUpDoorSigs( void )
  123. {
  124.   // this routine sets up all the signals availiable so you can checksignal() them
  125.   // or wait() on them or whatever....
  126.  
  127.   if (N_ND->NodeSettings.Iconified==FALSE)
  128.     N_ND->WinSig=DEF_WINSIG;
  129.   else
  130.     N_ND->WinSig=0L;
  131.  
  132.   if (N_ND->InformationOpen)
  133.     N_ND->InfoWinSig=DEF_INFOWINSIG;
  134.   else
  135.     N_ND->InfoWinSig=0L;
  136.  
  137.   if (N_ND->SettingsOpen)
  138.     N_ND->SettingsWinSig=DEF_SETTINGSWINSIG;
  139.   else
  140.     N_ND->SettingsWinSig=0L;
  141.  
  142.   N_ND->PortSig=DEF_PORTSIG;
  143.   N_ND->TimerSig=DEF_TIMERSIG;
  144. }
  145.  
  146.  
  147. void HandleMiscSigs( ULONG ReturnedSigs )
  148. {
  149.   // this routine handles all stuff like the sysop clicking on the node window
  150.   // or closing the watch screen etc. etc...
  151.  
  152.   ULONG class;
  153.   UWORD code;
  154.   struct Gadget *pgsel;
  155.   struct IntuiMessage *imsg;
  156.  
  157.   if (ReturnedSigs & N_ND->WinSig)
  158.   {
  159.     while ((NodeWnd) && (imsg=GT_GetIMsg(NodeWnd->UserPort)))
  160.     {
  161.       class=imsg->Class;
  162.       code=imsg->Code;
  163.       pgsel=(struct Gadget *)imsg->IAddress; /* Only reference if it is a gadget message */
  164.       GT_ReplyIMsg(imsg);
  165.       ProcessWindowNodeWnd(class, code, pgsel);
  166.     }
  167.   }
  168.  
  169.   if (ReturnedSigs & N_ND->ConWinSig)
  170.   {
  171.     while ((N_ND->ConWin) && (imsg=GT_GetIMsg(N_ND->ConWin->UserPort)))
  172.     {
  173.       class=imsg->Class;
  174.       code=imsg->Code;
  175.       pgsel=(struct Gadget *)imsg->IAddress; /* Only reference if it is a gadget message */
  176.       GT_ReplyIMsg(imsg);
  177.       ProcessConWindow(class, code, pgsel);
  178.     }
  179.   }
  180.  
  181.   if (ReturnedSigs & N_ND->InfoWinSig)
  182.   {
  183.     while ((InfoWin) && (imsg=GT_GetIMsg(InfoWin->UserPort)))
  184.     {
  185.       class=imsg->Class;
  186.       code=imsg->Code;
  187.       pgsel=(struct Gadget *)imsg->IAddress; /* Only reference if it is a gadget message */
  188.       GT_ReplyIMsg(imsg);
  189.       ProcessWindowInfoWin(class, code, pgsel);
  190.     }
  191.   }
  192.  
  193.   if (ReturnedSigs & N_ND->SettingsWinSig)
  194.   {
  195.     while ((SettingsWin) && (imsg=GT_GetIMsg(SettingsWin->UserPort)))
  196.     {
  197.       class=imsg->Class;
  198.       code=imsg->Code;
  199.       pgsel=(struct Gadget *)imsg->IAddress; /* Only reference if it is a gadget message */
  200.       GT_ReplyIMsg(imsg);
  201.       ProcessWindowSettingsWin(class, code, pgsel);
  202.     }
  203.   }
  204.  
  205.   if (ReturnedSigs & N_ND->PortSig)
  206.   {
  207.     HandleMsg(); // node can only be closed by a message from the CONTROL program
  208.   }
  209.  
  210.   if (ReturnedSigs & (1L << N_ND->OLMPort->mp_SigBit))
  211.   {
  212.     struct Message *Msg;
  213.  
  214.     while (Msg=GetMsg(N_ND->OLMPort))
  215.     {
  216.       FreeVec(Msg);
  217.     }
  218.   }
  219. }
  220.  
  221. ULONG WaitAllSigs(void)
  222. {
  223.   return(Wait((1L << N_ND->OLMPort->mp_SigBit) | N_ND->SettingsWinSig | N_ND->InfoWinSig |N_ND->WinSig | N_ND->PortSig | N_ND->ConSig | N_ND->SerSig | N_ND->ConWinSig | N_ND->TimerSig));
  224. }
  225.  
  226.  
  227. #define KEY_NONE 0
  228. #define KEY_ESCAPE 1
  229. #define KEY_CSI 2
  230.  
  231. ULONG CheckCSI(UBYTE ch,ULONG wherefrom)
  232. {
  233.   ULONG ReturnedSigs;
  234.   BOOL done=FALSE;
  235.   int csipos=0;
  236. //  int loop;
  237.  
  238.   if ((N_ND->char1==27 && ch=='[') || (ch==155))
  239.   {
  240.  
  241.     N_ND->char1=0;
  242.     while (!done)
  243.     {
  244.       // now, we have to be specific as to where we think the control sequence
  245.       // is coming from, for instance, say you had got the first byte of the
  246.       // control sequence from the serial port, you obviously wouldn't want
  247.       // any more of the control sequence coming from the console.. :-)
  248.  
  249.       if (wherefrom==GET_SERIAL)
  250.       {
  251.         if (!N_ND->SerWaiting) SendSerReadData();
  252.       }
  253.       if (wherefrom==GET_CONSOLE)
  254.       {
  255.         if (!N_ND->ConWaiting && N_ND->ConOK) ConReadData(1); // we only want to do a char at a time...
  256.       }
  257.       SetUpSigs();
  258.       ReturnedSigs=WaitAllSigs();
  259.       // handlemiscsigs() MAY close the console window.. so be careful!
  260.       // also N_ND->RequestShutdown MIGHT get set if the sysop clicks close
  261.       // on the control panel, BUT if we are in the middle of an escape sequence
  262.       // we don't want to know.
  263.       HandleMiscSigs(ReturnedSigs);
  264.  
  265.       while ( ((wherefrom==GET_SERIAL) && HandleSerSigs(ReturnedSigs)) ||
  266.               ((wherefrom==GET_CONSOLE) && HandleConSigs(ReturnedSigs)) )
  267.       {
  268.         if ( N_ND->IBuffer[0]>=0x40 && N_ND->IBuffer[0] <=0x7E)
  269.         {
  270.           N_ND->csistring[csipos]=N_ND->IBuffer[0];
  271.           csipos++;
  272.           done=TRUE;
  273.         }
  274.         else
  275.         {
  276.           N_ND->csistring[csipos]=N_ND->IBuffer[0];
  277.           csipos++;
  278.         }
  279.       }
  280.     }
  281.     N_ND->csistring[csipos]=0; // null terminate str..
  282.  
  283.     // note: csipos is same as doing strlen(N_ND->csistring)..
  284.  
  285.     return(KEY_CSI);
  286.  
  287.   }
  288.   else
  289.   {
  290.     if (ch==27)
  291.     {
  292.       N_ND->char1=27;
  293.       return(KEY_NONE);
  294.     }
  295.   }
  296.  
  297.   if (N_ND->char1==27)
  298.   {
  299.     N_ND->char1=0;
  300.     return(KEY_ESCAPE);
  301.   }
  302.   return(KEY_NONE);
  303. }
  304.  
  305. void handleescape( void )
  306. {
  307. //  puts("Escape Pressed!");
  308. }
  309.  
  310. // when writing data to the console or serial port we MUST use <ESC>[ and not 0x9B
  311. // cos then only amiga's would understand it! :-)  But hey! what a cool idea!
  312.  
  313. /* NOT USED ANYMORE!  only getline used them and I've had to modify that too much!
  314.   void CursorLeft( short num )
  315.   {
  316.     UBYTE outstr[6]; // csi+3digits+ansi terminator+null terminator
  317.     sprintf(outstr,"\033[%dD",num);
  318.     PutText(outstr);
  319.   }
  320.  
  321.   void CursorRight( short num )
  322.   {
  323.     UBYTE outstr[6]; // csi+3digits+ansi terminator+null terminator
  324.     sprintf(outstr,"\033[%dC",num);
  325.     PutText(outstr);
  326.   }
  327.  
  328.   void DeleteChars( short num )
  329.   {
  330.     UBYTE outstr[6]; // csi+3digits+ansi terminator+null terminator
  331.     sprintf(outstr,"\033[%dP",num);
  332.     PutText(outstr);
  333.   }
  334.  
  335.   void InsertChars( short num )
  336.   {
  337.     UBYTE outstr[6]; // csi+3digits+ansi terminator+null terminator
  338.     sprintf(outstr,"\033[%d@",num);
  339.     PutText(outstr);
  340.   }
  341. */
  342.  
  343. ULONG CheckFunctionKeys( void )
  344. {
  345.   // this routine checks the function keys, and depending on the
  346.   // N_ND->LoginType it does certain things...
  347.  
  348.   ULONG status=IN_NOTHING;
  349.  
  350. //  puts(N_ND->csistring);
  351.  
  352.   if (stricmp(N_ND->csistring,str_CSI_F7)==0)
  353.   {
  354.     CleanupNodeConsoleWin();
  355.   }
  356.   else
  357.   if (stricmp(N_ND->csistring,str_CSI_F8)==0)
  358.   {
  359.     ChangeConsoleMode(2); // swap between screen and window..
  360.     if ((N_ND->LoginType==LOGIN_NONE) && (N_ND->CurrentLine[0]==0)) status=IN_DISPLAYAWAIT;
  361.   }
  362.   else
  363.   if (N_ND->LoginType==LOGIN_NONE)
  364.   {
  365.     if (stricmp(N_ND->csistring,str_CSI_F1)==0) status=IN_LOGIN;      // Local Login
  366.     if (stricmp(N_ND->csistring,str_CSI_F2)==0) InitModem();          // Init Modem
  367.     if (stricmp(N_ND->csistring,str_CSI_F3)==0) status=IN_IMMEDIATE;  // Answer Modem Now
  368.     if (stricmp(N_ND->csistring,str_CSI_F4)==0)
  369.     {
  370.       if (N_ND->CurrentLine[0]==0) status=IN_DISPLAYAWAIT;            // Display Awaitscreen if no chars recieved yet..
  371.     }
  372.     if (stricmp(N_ND->csistring,str_CSI_F5)==0)                       // toggle modem debug
  373.     {
  374.       N_ND->NodeDevice.ModemDebug=!N_ND->NodeDevice.ModemDebug;
  375.     }
  376.     if (stricmp(N_ND->csistring,str_CSI_F6)==0)
  377.     {
  378.       // we have to fool the system into thinking that there's someone
  379.       // logged in so that we can run the door! :-)
  380.       N_ND->LoginType=LOGIN_LOCAL;
  381.       N_ND->OnlineStatus=OS_ONLINE;
  382.  
  383.       GoSystemDoor("ACCOUNTEDIT",NULL);
  384.  
  385.       // but not forgetting to put it back to how it was..
  386.       N_ND->LoginType=LOGIN_NONE;
  387.       N_ND->OnlineStatus=OS_OFFLINE;
  388.  
  389.       // and display the await screen again to tidy up..
  390.       status=IN_DISPLAYAWAIT;
  391.     }
  392.     if (stricmp(N_ND->csistring,str_CSI_F9)==0) status=IN_TERMINAL;
  393.     if (stricmp(N_ND->csistring,str_CSI_SF9)==0) status=IN_DIALOUT;
  394.     if (stricmp(N_ND->csistring,str_CSI_F10)==0) status=IN_SHUTDOWN;
  395.   }
  396.   else // Oooh someone's logged in and the sysop wants to do something to the user!
  397.   {
  398.     if (stricmp(N_ND->csistring,str_CSI_F1)==0)
  399.     {
  400.       // chat door running ?
  401.       if ((N_ND->ActiveDoor) && (iposition("SYSOPCHAT",N_ND->ActiveDoor->node.ln_Name)>=0))
  402.       {
  403.         status=IN_ENDCHAT;
  404.       }
  405.       else
  406.       {
  407.         GoSystemDoor("SYSOPCHAT",NULL);
  408.         status=IN_ENDCHAT;
  409.       }
  410.     }
  411.     else
  412.     if (stricmp(N_ND->csistring,str_CSI_F6)==0)
  413.     {
  414.       if ((N_ND->ActiveDoor) && (iposition("ACCOUNTEDIT",N_ND->ActiveDoor->node.ln_Name)<0))
  415.       {
  416.         GoSystemDoor("ACCOUNTEDIT","SYSOPONLY");
  417.       }
  418.     }
  419.     else
  420.     if (stricmp(N_ND->csistring,str_CSI_SF6)==0)
  421.     {
  422.       if ((N_ND->ActiveDoor) && (iposition("ACCOUNTEDIT",N_ND->ActiveDoor->node.ln_Name)<0))
  423.       {
  424.         GoSystemDoor("ACCOUNTEDIT","SYSOPONLY CALLONLY");
  425.       }
  426.     }
  427.     else
  428.     if (stricmp(N_ND->csistring,str_CSI_SF10)==0)
  429.     {
  430.       if (N_ND->LoginType==LOGIN_REMOTE) HangUp();
  431.       return(IN_LOSSCARRIER);
  432.     }
  433.   }
  434.   return(status);
  435. }
  436. /*  see defines.h
  437.  
  438. #define GL_NONE      0  // default
  439. #define GL_HISTORY   1  // if set history is enabled (up/down cursor keys)
  440. #define GL_LINEWRAP  2  // if maxlen is reached then data back to the last ' ' character is copied to N_ND->CurrentLineWrap and returns immediately
  441. #define GL_IMMEDIATE 4  // returns when maxlen is reached
  442. #define GL_NORETURN  8  // does not print a cr+lf when a) reached maxlen or b) timeout or c) return press
  443. #define GL_EDIT      16 // enables cursor left/right and backspace/delete
  444. #define GL_DISPLAY   32 // display chars (don't specify for "Press [return] to contine" type prompts)
  445. #define GL_SYSOP     64 // does not write to, or read from, the serial port
  446. #define GL_USECHARS  128 // see N_ND->CharsAllowed
  447. #define GL_NOBEEP    256 // use with GL_USECHARS if you don't want a beep when
  448.                          // the presses a key not in N_ND->CharsAllowed
  449. #define GL_NOOLM     512 // (No OLM) if set olm's will not inturrpt the user
  450. #define GL_NODISTURB 1024// Lets you use things like "Enter ID: [    ]" with out the ] moving
  451. #define GL_CVTUPPER  2048// converts input chars to uppercase as the keys are pressed!
  452.  
  453. */
  454.  
  455. void ReDrawLine(ULONG Flags, int *xpos)
  456. {
  457.   char cmovestr[20];
  458.  
  459.   if (Flags & GL_DISPLAY)
  460.   {
  461.     // now move back to the start of the string and erase it,
  462.     // then print the new string
  463.  
  464.     if (*xpos)
  465.     {
  466.       sprintf(cmovestr,"\033[%dD",*xpos);
  467.     }
  468.     if (Flags & GL_SYSOP)
  469.     {
  470.       if (*xpos) PutConText(cmovestr);
  471.       PutConText("\033[K");
  472.       PutConText(N_ND->CurrentLine);
  473.     }
  474.     else
  475.     {
  476.       if (*xpos) PutText(cmovestr);
  477.       PutText("\033[K");
  478.       PutText(N_ND->CurrentLine);
  479.     }
  480.   }
  481.   *xpos=strlen(N_ND->CurrentLine);
  482. }
  483.  
  484.  
  485. V_BOOL CheckRaw(ULONG Flags)
  486. {
  487.   V_BOOL GotSomeData=FALSE;
  488.  
  489.   N_ND->CurrentLine[0]=0;
  490.   N_ND->CurrentLine[1]=0;
  491.   if (!(Flags & CR_NOCONSOLE) && (N_ND->ConOK))    // fixed, 25/07/96
  492.   {
  493.     if (N_ND->ConWaiting) AbortConRead();
  494.     N_ND->ConRead->io_Command  = CMD_READ;
  495.     N_ND->ConRead->io_Data     = (APTR)N_ND->CurrentLine;
  496.     N_ND->ConRead->io_Length   = 1;
  497.  
  498.     ClrSignal(1L << N_ND->ConRPort->mp_SigBit);
  499.     SendIO((struct IORequest*)N_ND->ConRead);
  500.  
  501.     if (CheckIO((struct IORequest*)N_ND->ConRead))
  502.     {
  503.       WaitIO((struct IORequest*)N_ND->ConRead);
  504.       if (N_ND->ConRead->io_Actual)
  505.       {
  506.         GotSomeData=TRUE;
  507.         N_ND->CurrentLine[2]=1;
  508.       }
  509.     }
  510.     else
  511.     {
  512.       AbortIO((struct IORequest*)N_ND->ConRead);
  513.     }
  514.   }
  515.   if (!((GotSomeData) || (Flags & CR_NOSERIAL)) && (N_ND->SerOK)) // fixed, 25/07/96
  516.   {
  517.     if (SerQueryData()>0)
  518.     {
  519.       WaitSerReadBlock(N_ND->CurrentLine,1);
  520.       GotSomeData=TRUE;
  521.       N_ND->CurrentLine[2]=2;
  522.     }
  523.   }
  524.   return((V_BOOL)GotSomeData);
  525. }
  526.  
  527. ULONG Get_Line(ULONG Flags,char PasswordChar,ULONG MaxLen, ULONG Timeout, UBYTE *PromptStr)
  528. {
  529.   int editloop,editlen;
  530.   ULONG ReturnedSigs;
  531.   UBYTE CurrentChar[2]={0,0}; // 2 chars, use ¤tchar for null terminated string type..
  532.   int xpos=0;
  533.   ULONG csitype=0;
  534.   ULONG retval=IN_NOTHING; // this must NOT be returned to the caller!!!!!
  535.   struct TimerData *TD=NULL;
  536.   BOOL AddOK;
  537.   char *strptr;
  538.  
  539.   LONG HistoryNum=HistoryItems,OldHistNum=-1;
  540.   char cmovestr[20];
  541.  
  542.   if (N_ND->NodeFlags & NFLG_CTRLC) N_ND->NodeFlags-=NFLG_CTRLC;
  543.  
  544.  
  545.   N_ND->CurrentLine[0]=0; // null terminate the string..
  546.   N_ND->CurrentLineWrap[0]=0; // null terminate the string..
  547.  
  548.   if (Timeout)
  549.   {
  550.     TD=SubmitTimer(N_ND->NodeTimer,Timeout,0);
  551. //    if (TD) printf("Submitted a timer for %ld seconds\n",Timeout);
  552.   }
  553.  
  554.   if (PromptStr)
  555.   {
  556.     strNcpy(N_ND->CurrentLine,PromptStr,MaxLen > 0 ? MaxLen : LEN_CURRENTLINE);
  557.  
  558.     if (PasswordChar) // Convert promptstr to a blanked out string..
  559.     {
  560.       for (editloop=0;N_ND->CurrentLine[editloop];editloop++)
  561.       {
  562.         if (Flags & GL_SYSOP)
  563.         {
  564.           PutConChar(PasswordChar);
  565.         }
  566.         else
  567.         {
  568.           PutChar(PasswordChar);
  569.         }
  570.       }
  571.     }
  572.     else
  573.     {
  574.       if (Flags & GL_SYSOP)
  575.       {
  576.         PutConText(N_ND->CurrentLine);
  577.       }
  578.       else
  579.       {
  580.         PutText(N_ND->CurrentLine);
  581.       }
  582.     }
  583.     xpos=strlen(N_ND->CurrentLine);
  584.   }
  585.  
  586.   if (MaxLen==0) MaxLen=LEN_CURRENTLINE;
  587.  
  588.   if ((N_ND->LoginType==LOGIN_REMOTE) && (CarrierLost())) retval=IN_LOSSCARRIER;
  589.  
  590.   while (retval==IN_NOTHING)
  591.   {
  592.     // we only want to read the serial port if a) it's open and b) if we're
  593.     // still awaiting connect or someone is logged on..
  594.  
  595.     if (N_ND->SerOK && N_ND->LoginType !=LOGIN_LOCAL && (!(Flags & GL_SYSOP))  && (!(N_ND->NodeFlags & NFLG_BLOCKSERIAL)))
  596.     {
  597.       if (!N_ND->SerWaiting) SendSerReadData();
  598.     }
  599.  
  600.     // we ALWAYS want to read the console if the console window is open.
  601.     // cos the sysop might wanna do sommat!
  602.  
  603.     if (!N_ND->ConWaiting && N_ND->ConOK) ConReadData(1);
  604.  
  605.     SetUpSigs();
  606. //    if (Timeout)
  607. //    {
  608. //      printf("Timersig: %x\n",N_ND->TimerSig);
  609. //    }
  610.     ReturnedSigs=WaitAllSigs();
  611.     HandleMiscSigs(ReturnedSigs);
  612.  
  613.     // check olm's ?  *C* add an option/flag to NOT check for OLM's..
  614.     if ((!(N_ND->NodeFlags & NFLG_HANDLINGOLM)) && (!(Flags & GL_NOOLM)) && (ReturnedSigs & (1L << N_ND->OLMPort->mp_SigBit)) && (N_ND->NodeFlags & NFLG_OLMSWAITING))
  615.     {
  616.       GoSystemDoor("ReadOLM",NULL);
  617.  
  618.       xpos=0;
  619.       ReDrawLine(Flags,&xpos);
  620.     }
  621.  
  622.     if (Timeout)
  623.     {
  624.       if (TD)
  625.       {
  626.         if (CheckTimer(N_ND->NodeTimer,TD))
  627.         {
  628.           TD=NULL;
  629.           retval=IN_TIMEOUT;
  630.  
  631.           if ((Flags & GL_DISPLAY) && !(Flags & GL_NORETURN))
  632.           {
  633.             if (Flags & GL_SYSOP)
  634.             {
  635.               PutConText("\r\n");
  636.             }
  637.             else
  638.             {
  639.               PutText("\r\n");
  640.             }
  641.           }
  642.  
  643. //          puts("Timeout!");
  644.         }
  645.       }
  646. //      else
  647. //      puts("Error, no timer data!");
  648.     }
  649.  
  650.     if (N_ND->RequestShutdown) retval=IN_SHUTDOWN;
  651.     if (N_ND->LoginType==LOGIN_REMOTE && CarrierLost()) retval=IN_LOSSCARRIER;
  652.  
  653.     while (retval==IN_NOTHING && HandleConSerSigs(ReturnedSigs)) // swapped!
  654.     {
  655.       // key press, restart timer!
  656.       if (Timeout)
  657.       {
  658. //        puts("restarting timer!");
  659.         if (TD) AbortTimer(N_ND->NodeTimer,TD);
  660.         TD=SubmitTimer(N_ND->NodeTimer,Timeout,0);
  661. //        if (TD) puts("restarted ok!");
  662.       }
  663.       // ok, we got some data from somehwere...
  664.  
  665.       CurrentChar[0]=N_ND->IBuffer[0];
  666.  
  667.       // checkcsi() needs to know EXACTLY where to look for incoming data
  668.  
  669.       csitype=CheckCSI(CurrentChar[0],ReturnedSigs & N_ND->ConSig ? GET_CONSOLE : GET_SERIAL);
  670.       switch (csitype)
  671.       {
  672.         case KEY_CSI:
  673.           {
  674.             if (Flags & GL_EDIT)
  675.             {
  676.               if (strcmp(N_ND->csistring,str_CSI_CURSORLEFT)==0)
  677.               {
  678.                 if (xpos>0)
  679.                 {
  680.                   xpos--;
  681.                   if (Flags & GL_DISPLAY)
  682.                   {
  683.                     if (Flags & GL_SYSOP)
  684.                     {
  685.                       PutConText("\033[1D");
  686.                     }
  687.                     else
  688.                     {
  689.                       PutText("\033[1D");
  690. //                      CursorLeft(1);
  691.                     }
  692.                   }
  693.                 }
  694.               }
  695.               else
  696.               {
  697.                 if (strcmp(N_ND->csistring,str_CSI_CURSORRIGHT)==0)
  698.                 {
  699.                   if (xpos<strlen(N_ND->CurrentLine))
  700.                   {
  701.                     xpos++;
  702.                     if (Flags & GL_DISPLAY)
  703.                     {
  704.                       if (Flags & GL_SYSOP)
  705.                       {
  706.                         PutConText("\033[1C");
  707.                       }
  708.                       else
  709.                       {
  710.                         PutText("\033[1C");
  711.   //                      CursorRight(1);
  712.                       }
  713.                     }
  714.                   }
  715.                 }
  716.                 else
  717.                 {
  718.                   if ((Flags & GL_HISTORY) && (HistoryItems>0))
  719.                   {
  720.                     if (strcmp(N_ND->csistring,str_CSI_CURSORUP)==0)
  721.                     {
  722.                       if (HistoryNum>0)
  723.                       {
  724.                         HistoryNum--;
  725.                       }
  726.                     }
  727.  
  728.                     if (strcmp(N_ND->csistring,str_CSI_CURSORDOWN)==0)
  729.                     {
  730.                       if (HistoryNum<HistoryItems)
  731.                       {
  732.                         HistoryNum++;
  733.                       }
  734.                     }
  735.  
  736.                     if (HistoryNum!=OldHistNum)
  737.                     {
  738.                       if (HistoryNum<HistoryItems)
  739.                       {
  740.                         strNcpy(N_ND->CurrentLine,HBBS_ListName(HistoryList,HistoryNum),MaxLen);
  741.                         OldHistNum=HistoryNum;
  742.                       }
  743.                       else
  744.                       {
  745.                         N_ND->CurrentLine[0]=0; // erase the line.. :-)
  746.                         HistoryNum=HistoryItems;
  747.                         OldHistNum=-1;
  748.                       }
  749.                       ReDrawLine(Flags,&xpos);
  750.                     }
  751.                   }
  752.                 }
  753.               }
  754.             }
  755.             retval=CheckFunctionKeys();
  756.           }
  757.           break;
  758.         case KEY_ESCAPE:
  759.           handleescape();
  760.           // CheckCSI will leave one the character following the escape key
  761.           // in the buffer. so reset out mini string again..
  762.           CurrentChar[0]=N_ND->IBuffer[0];
  763.           // no break so we process the next char as well..
  764.         case KEY_NONE:
  765.           if (N_ND->LoginType!=LOGIN_NONE || ReturnedSigs & N_ND->SerSig)
  766.           {
  767.             if (CurrentChar[0]>=0x20) // i.e. not unprintable or a control char..
  768.             {
  769.               if (CurrentChar[0]==127) // DEL
  770.               {
  771.                 if (Flags & GL_EDIT)
  772.                 {
  773.                   editlen=strlen(N_ND->CurrentLine);
  774.                   if (xpos!=editlen)
  775.                   {
  776.                     for (editloop=xpos;editloop<(min(editlen,MaxLen));editloop++) // <= to copy the null terminator as well!
  777.                     {
  778.                       N_ND->CurrentLine[editloop]=N_ND->CurrentLine[editloop+1];
  779.                     }
  780.                     if (Flags & GL_DISPLAY)
  781.                     {
  782.                       if (Flags & GL_SYSOP)
  783.                       {
  784.                         PutConText("\033[1P");
  785.                       }
  786.                       else
  787.                       {
  788.                         PutText("\033[1P");
  789.                         if (Flags & GL_NODISTURB)
  790.                         {
  791.                           if (xpos==MaxLen-1)
  792.                           {
  793.                             strcpy(cmovestr,"\033[@");
  794.                           }
  795.                           else
  796.                           {
  797.                             sprintf(cmovestr,"\033[%dC\033[@\033[%dD",MaxLen-xpos-1,MaxLen-xpos-1);
  798.                           }
  799.                           PutText(cmovestr);
  800.                         }
  801.                       }
  802.                     }
  803.                   }
  804.                 }
  805.               }
  806.               else
  807.               {
  808.                 if (Flags & GL_CVTUPPER) CurrentChar[0]=toupper(CurrentChar[0]);
  809.  
  810.                 AddOK=FALSE;
  811.                 if (Flags & GL_USECHARS)
  812.                 {
  813.                   if (strchr(N_ND->CharsAllowed,CurrentChar[0]))
  814.                   {
  815.                     AddOK=TRUE;
  816.                   }
  817.                   else
  818.                   {
  819.                     // ooh, wrong char, lets do a beep..
  820.                     if (!(Flags & GL_NOBEEP))
  821.                     {
  822.                       // but only if we're allowed to!
  823.                       if (Flags & GL_SYSOP)
  824.                       {
  825.                         PutConChar(7); // 7 = BEEP char!
  826.                       }
  827.                       else
  828.                       {
  829.                         PutChar(7);
  830.                       }
  831.                     }
  832.                   }
  833.                 } else AddOK=TRUE;
  834.                 if (AddOK)
  835.                 {
  836.                   // ok, no function key pressed, so add the char to the end of the string...
  837.                   if ((editlen=strlen(N_ND->CurrentLine)) < min(LEN_CURRENTLINE,MaxLen))
  838.                   {
  839.                     if (xpos==editlen) // tag char on end ?
  840.                     {
  841.                       xpos++;
  842.                       strcat(N_ND->CurrentLine,CurrentChar);
  843.                       if (Flags & GL_DISPLAY)
  844.                       {
  845.                         if (Flags & GL_SYSOP)
  846.                         {
  847.                           if (PasswordChar) PutConChar(PasswordChar); else PutConChar(CurrentChar[0]);
  848.                         }
  849.                         else
  850.                         {
  851.                           if (PasswordChar) PutChar(PasswordChar); else PutChar(CurrentChar[0]);
  852.                         }
  853.                       }
  854.                     }
  855.                     else
  856.                     {
  857.                       if (Flags & GL_EDIT)
  858.                       {
  859.                         // gotta insert char!
  860.                         for (editloop=editlen+1; editloop>xpos ;editloop--) //+1 for null terminator
  861.                         {
  862.                           N_ND->CurrentLine[editloop]=N_ND->CurrentLine[editloop-1];
  863.                         }
  864.                         N_ND->CurrentLine[xpos]=CurrentChar[0];
  865.                         if (Flags & GL_DISPLAY)
  866.                         {
  867.                           if (Flags & GL_SYSOP)
  868.                           {
  869.                             PutConText("\033[1@");
  870.                             PutConChar(CurrentChar[0]);
  871.                           }
  872.                           else
  873.                           {
  874.                             PutText("\033[1@");
  875.                             PutChar(CurrentChar[0]);
  876.                             if (Flags & GL_NODISTURB)
  877.                             {
  878.                               sprintf(cmovestr,"\033[%dC\033[P\033[%dD",MaxLen-xpos-1,MaxLen-xpos-1);
  879.                               PutText(cmovestr);
  880.                             }
  881.                           }
  882.                         }
  883.                         xpos++;
  884.                       }
  885.                     }
  886.                   }
  887.                 }
  888.               }
  889.             }
  890.             else
  891.             {
  892.               switch (CurrentChar[0])
  893.               {
  894.                 case 13: // return
  895.                   if ((Flags & GL_DISPLAY) && !(Flags & GL_NORETURN)) PutText(str_CRLF); // linefeed...
  896.                   retval=IN_GOTLINE;
  897.                   break;
  898.  
  899.                 case 27: //escape
  900.                   handleescape();
  901.                   break;
  902.  
  903.                 case 3: //ctrl+c
  904.                   if (!(N_ND->NodeFlags & NFLG_CTRLC)) N_ND->NodeFlags+=NFLG_CTRLC;
  905.                   break;
  906.                 case 24: //ctrl+x, clear the line..
  907.                   N_ND->CurrentLine[0]=0;
  908.                   ReDrawLine(Flags,&xpos);
  909.                   break;
  910.  
  911.                 case 8: //backspace
  912.                   if (Flags & GL_EDIT)
  913.                   {
  914.                     if (xpos>0)
  915.                     {
  916.                       xpos--;
  917.                       editlen=strlen(N_ND->CurrentLine);
  918.                       for (editloop=xpos;editloop<editlen;editloop++) // <= to copy the null terminator as well!
  919.                       {
  920.                         N_ND->CurrentLine[editloop]=N_ND->CurrentLine[editloop+1];
  921.                       }
  922.                       if (Flags & GL_DISPLAY)
  923.                       {
  924.                         if (Flags & GL_SYSOP)
  925.                         {
  926.                           PutConText("\033[1D\033[1P");
  927.                         }
  928.                         else
  929.                         {
  930.                           if (Flags & GL_NODISTURB)
  931.                           {
  932.                             if (xpos==MaxLen-1)
  933.                             {
  934.                               strcpy(cmovestr,"\033[@");
  935.                             }
  936.                             else
  937.                             {
  938.                               sprintf(cmovestr,"\033[%dC\033[@\033[%dD",MaxLen-xpos-1,MaxLen-xpos-1);
  939.                             }
  940.                             PutText(cmovestr);
  941.                           }
  942.                           PutText("\033[1D\033[1P");
  943. //                          CursorLeft(1);
  944. //                          DeleteChars(1);
  945.                         }
  946.                       }
  947.                     }
  948.                   }
  949.                   break;
  950.               }
  951.             }
  952.           }
  953.           break;
  954.       }
  955.     }
  956.     if (retval==IN_NOTHING)
  957.     {
  958.       if ((strlen(N_ND->CurrentLine)==MaxLen) && (Flags & GL_IMMEDIATE))
  959.       {
  960.         retval=IN_GOTLINE;
  961.  
  962.         if (Flags & GL_LINEWRAP)
  963.         {
  964.           if (strptr=strrchr(N_ND->CurrentLine,' '))
  965.           {
  966.             if (Flags & GL_DISPLAY)
  967.             {
  968.               sprintf(cmovestr,"\033[%dD\033[K",strlen(N_ND->CurrentLine)-(strptr-N_ND->CurrentLine));
  969.               if (Flags & GL_SYSOP)
  970.               {
  971.                 PutConText(cmovestr);
  972.               }
  973.               else
  974.               {
  975.                 PutText(cmovestr);
  976.               }
  977.             }
  978.  
  979.             strcpy(N_ND->CurrentLineWrap,strptr+1);
  980.             *strptr=0;
  981.  
  982.             // *C* update the display!
  983.           }
  984.         }
  985.  
  986.  
  987.         if ((Flags & GL_DISPLAY) && !(Flags & GL_NORETURN)) PutText(str_CRLF); // linefeed...
  988.       }
  989.     }
  990.   };
  991.   if (TD) AbortTimer(N_ND->NodeTimer,TD);
  992.  
  993.  
  994.   if (Flags & GL_HISTORY)
  995.   {
  996.     if (N_ND->CurrentLine[0])
  997.     {
  998.       if (!NewStrNode(N_ND->CurrentLine,HistoryList))
  999.       {
  1000.         HistoryItems++;
  1001.       }
  1002.     }
  1003.   }
  1004.  
  1005.  
  1006.   if (retval==IN_LOSSCARRIER)
  1007.   {
  1008.     N_ND->OnlineStatus=OS_OFFLINE;
  1009.     if (Flags & GL_DISPLAY) PutConText(str_CRLF);
  1010.   }
  1011.   return(retval);
  1012. }
  1013.  
  1014. void RunDoor(char *doorname,char *options,BOOL DebugMode,BOOL ASync)
  1015. {
  1016.   // function to start a door
  1017.   // *C* have timeout on door, check file exists before attempting to run it...
  1018.  
  1019.   char cmd[BIG_STR],outstr[BIG_STR+300];
  1020. //  sprintf(cmd,"%s %d %s",doorname,N_NodeNum,options ? options : "\0");
  1021.   sprintf(outstr,"%d",N_NodeNum);
  1022.   replace(cmd,doorname,"{O}",options ? options : ""); //replace won't work with a null string
  1023.   replace(cmd,cmd,"{N}",outstr);
  1024.  
  1025.   // if doorlog is on then write to the doorlog file!
  1026.   if (N_ND->NodeSettings.DoorLog || N_ND->DoorLogOverride)
  1027.   {
  1028.     HBBS_GetDate(outstr);
  1029.     strcat(outstr," ");
  1030.     HBBS_GetTime(outstr+strlen(outstr));
  1031.     sprintf(outstr+strlen(outstr)," Handle: %s, Conf: %s, Door: %s\n",N_ND->User.CallData.Handle,N_ND->CurrentConf ? N_ND->CurrentConf->node.ln_Name : "None Joined",cmd);
  1032.     HBBS_AppendStrToFile(N_ND->NodeSettings.DoorLogFile,outstr);
  1033.   }
  1034.  
  1035.   if (DebugMode)
  1036.   {
  1037.  
  1038.     printf("DOOR DEBUG MODE ON - Start the door with the settings below!\n"
  1039.            "==============================================================================\n"
  1040.            "%s\n"
  1041.            "==============================================================================\n",cmd);
  1042.   }
  1043.   else
  1044.   {
  1045.     HBBS_RunDOSCMD(cmd,ASync);
  1046.   }
  1047. }
  1048.  
  1049. struct MsgPort* CreateDoorStartPort( void )
  1050. {
  1051.   struct MsgPort *DP=NULL;
  1052.   sprintf(N_ND->DoorStartPortName,"DoorStart_N%d_D%d",N_ND->NodeNum,N_ND->DoorsRunning+1);
  1053.   DP=CreatePort(N_ND->DoorStartPortName,0);
  1054.   return(DP);
  1055. }
  1056.  
  1057. BOOL CheckDoorStarted(struct MsgPort *DP,char *systemoptions)
  1058. {
  1059.   struct DoorActivityMsg *DM;
  1060.   BOOL retval=FALSE;
  1061.  
  1062.   while (DM=(struct DoorActivityMsg *)GetMsg(DP))
  1063.   {
  1064.     N_ND->ActiveDoor->SystemOptions=systemoptions;
  1065.     ReplyMsg((struct Message *)DM);
  1066.     retval=TRUE;
  1067.   }
  1068.   return(retval);
  1069. }
  1070.  
  1071. void GoDoor(char *doorname,char *systemoptions,char *options,BOOL DebugMode)
  1072. {
  1073.   ULONG ReturnedSigs;
  1074.   struct DoorData *CurrentDoor;
  1075.   struct TimerData *TD;
  1076.   BOOL timeout,doorstarted;
  1077.   struct MsgPort *DP;
  1078.   char *clinesave=N_ND->CurrentLine; // save old line..
  1079.  
  1080. //  if (PathOK(doorname)) // does door exist ?
  1081. //  {
  1082. //    strcpy(N_ND->Action,"Loading Door!");
  1083. //    DOOR_UpdateNodeStatus(UPD_ACTION);
  1084.  
  1085.     if (N_ND->CurrentLine=AllocVec(LEN_CURRENTLINE,MEMF_PUBLIC))
  1086.     {
  1087.       N_ND->CurrentLine[0]=0;
  1088.  
  1089.                                             //*C* uncomment! make it a sysop definable setting
  1090.       if (TD=SubmitTimer(N_ND->NodeTimer,300/*TIMEOUT_DOORLOAD*/,0))
  1091.       {
  1092.         timeout=FALSE;
  1093.         doorstarted=FALSE;
  1094.  
  1095.         if (DP=CreateDoorStartPort())
  1096.         {
  1097.           N_ND->ActiveDoor=NULL;
  1098.           RunDoor(doorname,options,DebugMode,TRUE);
  1099.  
  1100. //        strcpy(N_ND->Action,"Waiting For Door");
  1101. //        DOOR_UpdateNodeStatus(UPD_ACTION);
  1102.  
  1103.           do
  1104.           {
  1105.             Wait (1L<<DP->mp_SigBit | DEF_PORTSIG );
  1106.             doorstarted=CheckDoorStarted(DP,systemoptions);
  1107.             if (timeout=CheckTimer(N_ND->NodeTimer,TD))
  1108.             {
  1109.               TD=NULL;
  1110.             }
  1111.           } while(doorstarted==FALSE && timeout==FALSE);
  1112.  
  1113.           DeletePort(DP);
  1114.  
  1115.           if (timeout)
  1116.           {
  1117.             HBBS_LogError(N_ND->NodeSettings.NodeLogFile,ERR_DOORTIMEOUT,doorname,TYPE_WARNING);
  1118.           }
  1119.           else
  1120.           {
  1121.             if (TD) AbortTimer(N_ND->NodeTimer,TD);
  1122.  
  1123.             strNcpy(N_ND->Action,N_ND->ActiveDoor->node.ln_Name,MAX_ACTION_LEN);
  1124.             DOOR_UpdateNodeStatus(UPD_ACTION);
  1125.  
  1126.             if (N_ND->ActiveDoor!=NULL)
  1127.             {
  1128.               // wait until the door stops!
  1129.  
  1130.               CurrentDoor=N_ND->ActiveDoor;
  1131.               do
  1132.               {
  1133.                 SetUpDoorSigs();
  1134.                 ReturnedSigs=Wait(N_ND->ConWinSig |
  1135.                                   N_ND->SettingsWinSig |
  1136.                                   N_ND->InfoWinSig |
  1137.                                   N_ND->WinSig |
  1138.                                   N_ND->PortSig);
  1139.  
  1140.                 HandleMiscSigs(ReturnedSigs);
  1141.  
  1142.                 // while the door is started we should check for function key presses
  1143.                 // and so on... (which is handled by HandleDoorMsg())
  1144.  
  1145.  
  1146.                 // repeat wait loop until the door is finished, can detect by looking to see
  1147.                 // what the value of the door pointer is when it starts, and then keep comparing
  1148.                 // that to the the ActiveDoor pointer, if they differ the door has closed (as
  1149.                 // the ActiveDoor Pointer would point to a different door or to NULL...
  1150.               } while (N_ND->ActiveDoor==CurrentDoor);
  1151.               if (DebugMode) puts(N_ND->DoorReturn);
  1152.             }
  1153.           }
  1154.         }
  1155.         else
  1156.         {
  1157.           if (TD) AbortTimer(N_ND->NodeTimer,TD);
  1158.         }
  1159.       }
  1160.       FreeVec(N_ND->CurrentLine);
  1161.       N_ND->CurrentLine=clinesave;
  1162.     }
  1163. /*
  1164.   }
  1165.   else
  1166.   {
  1167.     sprintf(outstr,"The door file (%s) is missing!\r\n",doorname);
  1168.     PutText(outstr);
  1169.     HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,outstr,TYPE_WARNING);
  1170.   }
  1171. */
  1172.   if (N_ND->ActiveDoor)
  1173.   {
  1174.     strNcpy(N_ND->Action,N_ND->ActiveDoor->node.ln_Name,MAX_ACTION_LEN);
  1175.     DOOR_UpdateNodeStatus(UPD_ACTION);
  1176.   }
  1177. }
  1178.  
  1179. void PrintList( struct List *list)
  1180. {
  1181.   struct Node *node;
  1182.   for (node = list->lh_Head ; node->ln_Succ ; node =node->ln_Succ)
  1183.   {
  1184.     puts(node->ln_Name);
  1185.   }
  1186. }
  1187.  
  1188. void CheckDoorTypes(char *actualtype,char *cmd,char *options)
  1189. {
  1190.   char tmpstr[BIG_STR],numstr[5];
  1191.  
  1192.   sprintf(numstr,"%d",N_NodeNum);
  1193.   replace(tmpstr,cmd,"{N}",numstr);
  1194.   replace(tmpstr,tmpstr,"{O}",options);
  1195.  
  1196.   if (stricmp(actualtype,"SCREEN")==0)
  1197.   {
  1198.     DisplayScreen(tmpstr);
  1199.   }
  1200.   else
  1201.   {
  1202.     if (stricmp(actualtype,"SSCREEN")==0)
  1203.     {
  1204.       DisplaySpecialScreen(tmpstr);
  1205.     }
  1206.     else
  1207.     {
  1208.       if (stricmp(actualtype,"CLS")==0)
  1209.       {
  1210.         PutText(ANSI_CLS);
  1211.       }
  1212.       else
  1213.       {
  1214.         if (stricmp(actualtype,"PAUSE")==0)
  1215.         {
  1216.           PausePrompt(tmpstr,0);
  1217.         }
  1218.         else
  1219.         {
  1220.           if (stricmp(actualtype,"ECHO")==0)
  1221.           {
  1222.             PutText(tmpstr);
  1223.             PutText("\r\n");
  1224.           }
  1225.           else
  1226.           {
  1227.             if (stricmp(actualtype,"DOS")==0)
  1228.             {
  1229.               HBBS_RunDOSCMD(tmpstr,FALSE);
  1230.             }
  1231.           }
  1232.         }
  1233.       }
  1234.     }
  1235.   }
  1236. }
  1237.  
  1238. #define GOSYS_CONF 1
  1239. #define GOSYS_NODE 2
  1240. #define GOSYS_CMDS 3
  1241.  
  1242. V_BOOL GoSystemDoor( char *doorname, char *options )
  1243. {
  1244.   /* must search the SYSTEM door list in the commands dir for first the conf,
  1245.   then the node and finally the hbbs:commands directories.. when it finds
  1246.   it it runs it, note that there may be more than one door to call at a time
  1247.   as you may define more than one door for each system function. e.g.
  1248.  
  1249.   Examine_Type_1=HBBS
  1250.   Examine_DOOR_1=HBBS:Doors/User/Examine/Examine.HBBS
  1251.   Examine_Param_1=
  1252.  
  1253.   Examine_Type_2=HBBS
  1254.   Examine_DOOR_2=HBBS:Doors/User/DIZTimeAdd/DIZTimeAdd.HBBS
  1255.   Examine_Param_2=[=- Uploaded At HH:MM -=]
  1256.  
  1257.   Examine_Type_3=HBBS
  1258.   Examine_DOOR_3=HBBS:Doors/User/Sentby/Sentby.HBBS
  1259.   Examine_Param_3=Sent,Cps,Node
  1260.  
  1261.   note: if you have say Examine_Type_1 in hbbs:conferences/newuser/commands/system
  1262.   and in hbbs:commands/system the set of commands in hbbs:commands/system WILL NOT
  1263.   be run as the former file has priority over the latter.
  1264.  
  1265.   */
  1266.  
  1267.   UBYTE filename[BIG_STR],*optionname,*actualparam=NULL,*actualtype=NULL;
  1268.   V_BOOL done=FALSE,DebugMode;
  1269.   short whichfile;
  1270.   struct CfgFileData *CfgFile;
  1271.   struct List *CmdList=NULL;
  1272.   struct Node *node;
  1273.   short doornum;
  1274.  
  1275.   N_ND->DoorReturn[0]=0; // null terminate string...
  1276.   N_ND->DoorContinue=TRUE;
  1277.  
  1278.   for (whichfile=GOSYS_CONF;whichfile<=GOSYS_CMDS && !done;whichfile++)
  1279.   {
  1280.     if (stricmp("AWAIT",doorname)!=0 && stricmp("ACCOUNTEDIT",doorname)!=0 && N_ND->OnlineStatus==OS_OFFLINE)
  1281.     {
  1282.       done=TRUE;
  1283.     }
  1284.     else
  1285.     {
  1286.       filename[0]=0;
  1287.       switch(whichfile)
  1288.       {
  1289.         case GOSYS_CONF:
  1290.           if (N_ND->CurrentConf) // have we joined a conf yet ?
  1291.           {
  1292.             strcpy(filename,N_ND->CurrentConf->ConfPath);
  1293.             strcat(filename,FILENAME_CMDSSYSTEM);
  1294.           }
  1295.           break;
  1296.         case GOSYS_NODE:
  1297.           strcpy(filename,N_ND->NodeLocation);
  1298.           strcat(filename,FILENAME_CMDSSYSTEM);
  1299.           break;
  1300.         case GOSYS_CMDS:
  1301.           strcpy(filename,FILE_HBBS);
  1302.           strcat(filename,FILENAME_CMDSSYSTEM);
  1303.           break;
  1304.       }
  1305.       if (filename[0]) // string present ?
  1306.       {
  1307.         if (optionname=AllocVec(strlen(doorname)+10,MEMF_PUBLIC))
  1308.         {
  1309.           strcpy(optionname,doorname);
  1310.           strcat(optionname,"_Door");
  1311.           if (CfgFile=HBBS_LoadConfig(filename,LCFG_NONE))
  1312.           {
  1313.             if (HBBS_GetSetting(CfgFile,(void *)&CmdList,VTYPE_STRINGLIST,optionname,OPT_MULTI))
  1314.             {
  1315.               for (doornum=1,node = CmdList->lh_Head ; N_ND->DoorContinue && node->ln_Succ ; node =node->ln_Succ,doornum++)
  1316.               {
  1317.                 actualtype=NULL;
  1318.                 sprintf(optionname,"%s_Type_%d",doorname,doornum);
  1319.                 if (HBBS_GetSetting(CfgFile,(void *)&actualtype,VTYPE_STRING,optionname,OPT_SINGLE))
  1320.                 {
  1321.                   actualparam=NULL;
  1322.                   sprintf(optionname,"%s_Param_%d",doorname,doornum);
  1323.                   HBBS_GetSetting(CfgFile,(void *)&actualparam,VTYPE_STRING,optionname,OPT_SINGLE);
  1324.                   if (!actualparam) actualparam=DupStr("");
  1325.                   if (actualparam)
  1326.                   {
  1327.                     done=TRUE;
  1328.  
  1329.                     DebugMode=FALSE;
  1330.  
  1331.                     sprintf(optionname,"%s_Debug_%d",doorname,doornum);
  1332.                     HBBS_GetSetting(CfgFile,(void *)&DebugMode,VTYPE_BOOL,optionname,OPT_SINGLE);
  1333.  
  1334.                     if (stricmp(actualtype,"HBBS")==0) //changed from "NORMAL" on 1-JULY-96
  1335.                     {
  1336.                       GoDoor(node->ln_Name,actualparam,options,DebugMode);
  1337.                     }
  1338.                     else
  1339.                     {
  1340.                       if (stricmp(actualtype,"CLI")==0)
  1341.                       {
  1342.                         RunDoor(node->ln_Name,options,DebugMode,FALSE);
  1343.                       }
  1344.                       else
  1345.                       {
  1346.                         CheckDoorTypes(actualtype,node->ln_Name,options);
  1347.                       }
  1348.                     }
  1349.                     FreeStr(actualparam);
  1350.                   }
  1351.                   FreeStr(actualtype);
  1352.                 }
  1353.               }
  1354.               FreeStrList(CmdList);
  1355.             }
  1356.             HBBS_FlushConfig(CfgFile);
  1357.           }
  1358.           FreeVec(optionname);
  1359.         }
  1360.       }
  1361.     }
  1362.   }
  1363.   return(done);
  1364. }
  1365.  
  1366. short WhatAccessNode(V_SMALLNUM accesslevel)
  1367. {
  1368.   // returns the struct node number of the specified access level
  1369.   // mainly used when you want to find the name of an access level
  1370.  
  1371.   short retval=-1;
  1372.   char tmpstr[10];
  1373.   short loop;
  1374.   struct Node *node;
  1375.  
  1376.  
  1377.   sprintf(tmpstr,"%d",accesslevel);
  1378.  
  1379.   for (loop=0,node = BBSGlobal->AcsLevelList->lh_Head ; node->ln_Succ && retval==-1 ; node =node->ln_Succ,loop++)
  1380.   {
  1381.     if (strcmp(tmpstr,node->ln_Name)==0)
  1382.     {
  1383.       retval=loop;
  1384.     }
  1385.   }
  1386.   return(retval);
  1387. }
  1388.  
  1389. #define GOUSER_CONF 1
  1390. #define GOUSER_NODE 2
  1391. #define GOUSER_CMDS 3
  1392.  
  1393.  
  1394. V_BOOL GoUserDoor( char *doorname, char *options )
  1395. {
  1396.  
  1397.   /* this door must first determine the current access level, then scan the following
  1398.      files to find out what door to run.
  1399.  
  1400.      CurrentConf/Commands/Level_XX
  1401.      CurrentConf/Commands/AllLevels
  1402.      Currentnode/Commands/Level_XX
  1403.      Currentnode/Commands/AllLevels
  1404.      HBBS:Commnds/Level_XX
  1405.      HBBS:Commnds/AllLevels
  1406.  
  1407.      then when it finds the door to run it calls it up!
  1408.  
  1409.   */
  1410.  
  1411.   UBYTE dirname[BIG_STR],filename[BIG_STR],*optionname,*actualparam=NULL,*actualtype=NULL;
  1412.   V_BOOL done=FALSE,DebugMode,SearchedAll;
  1413.   short whichfile;
  1414.   struct CfgFileData *CfgFile;
  1415.   struct List *CmdList=NULL;
  1416.   struct Node *node;
  1417.   short doornum,CurrentAccess;
  1418.  
  1419.   N_ND->DoorReturn[0]=0; // null terminate string...
  1420.   N_ND->DoorContinue=TRUE;
  1421.  
  1422.   for (whichfile=GOUSER_CONF;whichfile<=GOUSER_CMDS && !done;whichfile++)
  1423.   {
  1424.     dirname[0]=0;
  1425.     filename[0]=0;
  1426.     switch(whichfile)
  1427.     {
  1428.       case GOUSER_CONF:
  1429.         if (N_ND->CurrentConf) // have we joined a conf yet ?
  1430.         {
  1431.           sprintf(dirname,"%sCommands/",N_ND->CurrentConf->ConfPath);
  1432.         }
  1433.         break;
  1434.       case GOUSER_NODE:
  1435.         sprintf(dirname,"%sCommands/",N_ND->NodeLocation);
  1436.         break;
  1437.       case GOUSER_CMDS:
  1438.         strcpy(dirname,"HBBS:Commands/");
  1439.         break;
  1440.     }
  1441.     if (dirname[0]) // string present ? cos it might not be if we ain't in a conf..
  1442.     {
  1443.       // ok, no we know where to look for the commands, so we gotta check
  1444.       // "Level_<access>" downto "Level_00" until we find it, if it ain't there then
  1445.       // we have to check "All_Levels"
  1446.  
  1447.       SearchedAll=FALSE;
  1448.       CurrentAccess=WhatAccessNode(N_ND->User.CallData.Access);
  1449.  
  1450.       do
  1451.       {
  1452.         if (CurrentAccess<0)
  1453.         {
  1454.           sprintf(filename,"%sAll_Levels",dirname);
  1455.           SearchedAll=TRUE;
  1456.         }
  1457.         else
  1458.         {
  1459.           node=GetNode(BBSGlobal->AcsLevelList,CurrentAccess);
  1460.  
  1461.           sprintf(filename,"%sLevel_%s",dirname,node->ln_Name);
  1462.         }
  1463.  
  1464.         if (optionname=AllocVec(strlen(doorname)+10,MEMF_PUBLIC))
  1465.         {
  1466.           sprintf(optionname,"%s_Door",doorname);
  1467.           if (CfgFile=HBBS_LoadConfig(filename,LCFG_NONE))
  1468.           {
  1469.             if (HBBS_GetSetting(CfgFile,(void *)&CmdList,VTYPE_STRINGLIST,optionname,OPT_MULTI))
  1470.             {
  1471.               for (doornum=1,node = CmdList->lh_Head ; N_ND->DoorContinue && node->ln_Succ ; node =node->ln_Succ,doornum++)
  1472.               {
  1473.                 actualtype=NULL;
  1474.                 sprintf(optionname,"%s_Type_%d",doorname,doornum);
  1475.                 if (HBBS_GetSetting(CfgFile,(void *)&actualtype,VTYPE_STRING,optionname,OPT_SINGLE))
  1476.                 {
  1477.                   actualparam=NULL;
  1478.                   sprintf(optionname,"%s_Param_%d",doorname,doornum);
  1479.                   HBBS_GetSetting(CfgFile,(void *)&actualparam,VTYPE_STRING,optionname,OPT_SINGLE);
  1480.                   if (!actualparam) actualparam=DupStr("");
  1481.                   if (actualparam)
  1482.                   {
  1483.                     DebugMode=FALSE;
  1484.                     if (stricmp(actualtype,"HBBS")==0)
  1485.                     {
  1486.                       sprintf(optionname,"%s_Debug_%d",doorname,doornum);
  1487.                       HBBS_GetSetting(CfgFile,(void *)&DebugMode,VTYPE_BOOL,optionname,OPT_SINGLE);
  1488.  
  1489.                       GoDoor(node->ln_Name,actualparam,options,DebugMode);
  1490.                     }
  1491.                     else
  1492.                     {
  1493.                       if (stricmp(actualtype,"CLI")==0)
  1494.                       {
  1495.                         RunDoor(node->ln_Name,options,DebugMode,FALSE);
  1496.                       }
  1497.                       else
  1498.                       {
  1499.                         CheckDoorTypes(actualtype,node->ln_Name,options);
  1500.                       }
  1501.                     }
  1502.                     FreeStr(actualparam);
  1503.                   }
  1504.                   FreeStr(actualtype);
  1505.                 }
  1506.               }
  1507.               FreeStrList(CmdList);
  1508.               done=TRUE;
  1509.             }
  1510.             HBBS_FlushConfig(CfgFile);
  1511.           }
  1512.           FreeVec(optionname);
  1513.         }
  1514.         CurrentAccess--;
  1515.  
  1516.       } while (!( done || SearchedAll));
  1517.  
  1518.     }
  1519.   }
  1520.   return(done);
  1521. }
  1522.  
  1523. // *M* Move routines into HBBSNode.C
  1524.  
  1525. void Add_Last_Caller(char *data)
  1526. {
  1527.   struct Node *node;
  1528.  
  1529.   if (N_ND->Current_Last_Callers==N_ND->Max_Last_Callers)
  1530.   {
  1531.     node=RemTail(N_ND->Last_Callers);
  1532.     FreeStr(node->ln_Name);
  1533.     FreeVec(node);
  1534.     N_ND->Current_Last_Callers--;
  1535.   }
  1536.   if (node=(struct Node*)AllocVec(sizeof(struct Node),MEMF_PUBLIC|MEMF_CLEAR))
  1537.   {
  1538.     node->ln_Name=DupStr(data);
  1539.     AddHead(N_ND->Last_Callers,node);
  1540.     N_ND->Current_Last_Callers++;
  1541.   }
  1542.   UpdateInfoWin();
  1543.   SendRequest(REQ_UPDATEINFO);
  1544. }
  1545.  
  1546. void Add_Last_PWFail(char *data)
  1547. {
  1548.   struct Node *node;
  1549.  
  1550.   if (N_ND->Current_Last_PWFails==N_ND->Max_Last_PWFails)
  1551.   {
  1552.     node=RemTail(N_ND->Last_PWFails);
  1553.     FreeStr(node->ln_Name);
  1554.     FreeVec(node);
  1555.     N_ND->Current_Last_PWFails--;
  1556.   }
  1557.   if (node=(struct Node*)AllocVec(sizeof(struct Node),MEMF_PUBLIC|MEMF_CLEAR))
  1558.   {
  1559.     node->ln_Name=DupStr(data);
  1560.     AddHead(N_ND->Last_PWFails,node);
  1561.     N_ND->Current_Last_PWFails++;
  1562.   }
  1563.   UpdateInfoWin();
  1564.   SendRequest(REQ_UPDATEINFO);
  1565. }
  1566.  
  1567. void Add_Last_Upload(char *data)
  1568. {
  1569.   struct Node *node;
  1570.  
  1571.   if (N_ND->Current_Last_Uploads==N_ND->Max_Last_Uploads)
  1572.   {
  1573.     node=RemTail(N_ND->Last_Uploads);
  1574.     FreeStr(node->ln_Name);
  1575.     FreeVec(node);
  1576.     N_ND->Current_Last_Uploads--;
  1577.   }
  1578.   if (node=(struct Node*)AllocVec(sizeof(struct Node),MEMF_PUBLIC|MEMF_CLEAR))
  1579.   {
  1580.     node->ln_Name=DupStr(data);
  1581.     AddHead(N_ND->Last_Uploads,node);
  1582.     N_ND->Current_Last_Uploads++;
  1583.   }
  1584.   UpdateInfoWin();
  1585.   SendRequest(REQ_UPDATEINFO);
  1586. }
  1587.  
  1588.  
  1589. #define DSS_CONF 1
  1590. #define DSS_NODE 2
  1591. #define DSS_HBBS 3
  1592. #define DSS_ERR  4
  1593.  
  1594. V_BOOL DisplaySpecialScreen(char *ScreenName)
  1595. {
  1596.   char filename[BIG_STR];
  1597.   BOOL TriedAllLevels,Done=FALSE;
  1598.   struct Node *node;
  1599.  
  1600.   short whichdir=DSS_CONF;
  1601.   short CurrentAccess;
  1602.  
  1603.   do
  1604.   {
  1605.     filename[0]=0;
  1606.     if (N_ND->User.Valid)
  1607.     {
  1608.       TriedAllLevels=FALSE;
  1609.       CurrentAccess=WhatAccessNode(N_ND->User.CallData.Access);
  1610.     }
  1611.     else
  1612.     {
  1613.       CurrentAccess=-1;
  1614.     }
  1615.  
  1616.     do
  1617.     {
  1618.       switch(whichdir)
  1619.       {
  1620.         case DSS_CONF:
  1621.           if (N_ND->CurrentConf)
  1622.           {
  1623.             strcpy(filename,N_ND->CurrentConf->ConfPath);
  1624.           }
  1625.           break;
  1626.         case DSS_NODE:
  1627.           strcpy(filename,N_ND->NodeLocation);
  1628.           break;
  1629.         case DSS_HBBS:
  1630.           strcpy(filename,"HBBS:");
  1631.           break;
  1632.       }
  1633.  
  1634.       if (filename)
  1635.       {
  1636.         if (CurrentAccess<0) TriedAllLevels=TRUE;
  1637.  
  1638.         strcat(filename,DIRNAME_SCREENSSPECIAL);
  1639.         strcat(filename,ScreenName);
  1640.  
  1641.         if (N_ND->User.Valid && !TriedAllLevels)
  1642.         {
  1643.           // add access level _XX here..
  1644.  
  1645.           node=GetNode(BBSGlobal->AcsLevelList,CurrentAccess);
  1646.           CurrentAccess--;
  1647.           strcat(filename,"_");
  1648.           strcat(filename,node->ln_Name);
  1649.         }
  1650.         if (N_ND->User.Valid)
  1651.         {
  1652.           node=GetNode(BBSGlobal->LanguageExtn,N_ND->User.CallData.Language-1); //offset starts at 1
  1653.         }
  1654.         else
  1655.         {
  1656.           node=BBSGlobal->LanguageExtn->lh_Head;
  1657.         }
  1658.         strcat(filename,node->ln_Name);  // *C* Change To Users Selection
  1659.  
  1660.         Done=DisplayScreen(filename);
  1661.  
  1662.       } else TriedAllLevels=TRUE;
  1663.  
  1664.     } while (!TriedAllLevels && !Done);
  1665.  
  1666.  
  1667.     whichdir++;
  1668.  
  1669.   } while (! ((Done) || (whichdir==DSS_ERR)) );
  1670.   return(Done);
  1671. }
  1672.  
  1673. void SaveFileTags( void )
  1674. {
  1675.   struct CfgFileData *cfgfile;
  1676.   char tmpstr[BIG_STR];
  1677.   char optionstr[20];
  1678.   struct TaggedFile *filetagnode;
  1679.   int loop=0;
  1680.  
  1681.   sprintf(tmpstr,"HBBS:System/Data/Users/%d/TaggedFiles.CFG",N_ND->User.CallData.UserID);
  1682.  
  1683.   if (cfgfile=HBBS_CreateConfig(tmpstr))
  1684.   {
  1685.     // this item is ignored, it's just for the sysop's benefit so he can look at a file and see whose tags are in it..
  1686.  
  1687.     HBBS_AddCfgItem(cfgfile,"UserName",N_ND->User.CallData.Handle);
  1688.  
  1689.  
  1690.     for (filetagnode = (struct TaggedFile *)N_ND->TaggedFileList->lh_Head ; filetagnode->node.ln_Succ ; filetagnode =(struct TaggedFile*)filetagnode->node.ln_Succ)
  1691.     {
  1692.       loop++;
  1693.  
  1694.  
  1695.       if (filetagnode=(struct TaggedFile *)GetNode(N_ND->TaggedFileList,loop-1)) // get the node
  1696.       {
  1697.  
  1698.         sprintf(optionstr,"FileName_%d",loop);
  1699.         HBBS_AddCfgItem(cfgfile,optionstr,filetagnode->node.ln_Name);
  1700.  
  1701.         sprintf(optionstr,"WarezFile_%d",loop);
  1702.         HBBS_AddCfgItem(cfgfile,optionstr,filetagnode->WarezFile ? "YES" : "NO");
  1703.  
  1704.         sprintf(optionstr,"ConferenceNum_%d",loop);
  1705.         sprintf(tmpstr,"%d",filetagnode->ConferenceNum);
  1706.         HBBS_AddCfgItem(cfgfile,optionstr,tmpstr);
  1707.  
  1708.         sprintf(optionstr,"FileSize_%d",loop);
  1709.         sprintf(tmpstr,"%d",filetagnode->FileSize);
  1710.         HBBS_AddCfgItem(cfgfile,optionstr,tmpstr);
  1711.       }
  1712.     }
  1713.     HBBS_SaveConfig(cfgfile);
  1714.     HBBS_FlushConfig(cfgfile);
  1715.   }
  1716. }
  1717.  
  1718. void LoadFileTags( void )
  1719. {
  1720.   struct CfgFileData *cfgfile;
  1721.   char tmpstr[BIG_STR];
  1722.   char optionstr[20];
  1723.   char *strptr;
  1724.   struct TaggedFile *filetagnode;
  1725.   BOOL Error=FALSE;
  1726.   N_ND->TaggedFiles=0;
  1727.  
  1728.   // reinitialise list..
  1729.   NewList(N_ND->TaggedFileList);
  1730.  
  1731.   sprintf(tmpstr,"HBBS:System/Data/Users/%d/TaggedFiles.CFG",N_ND->User.CallData.UserID);
  1732.  
  1733.   if (cfgfile=HBBS_LoadConfig(tmpstr,LCFG_NONE))
  1734.   {
  1735.     do
  1736.     {
  1737.       Error=TRUE;
  1738.       strptr=NULL;
  1739.  
  1740.       sprintf(optionstr,"FileName_%d",N_ND->TaggedFiles+1);
  1741.       if (HBBS_GetSetting(cfgfile,(void *)&strptr,VTYPE_STRING,optionstr,OPT_SINGLE))
  1742.       {
  1743.         if (filetagnode=AllocVec(sizeof(struct TaggedFile),MEMF_PUBLIC))
  1744.         {
  1745.           N_ND->TaggedFiles++;
  1746.           filetagnode->node.ln_Name=strptr;
  1747.  
  1748.  
  1749.           sprintf(optionstr,"WarezFile_%d",N_ND->TaggedFiles);
  1750.           if (HBBS_GetSetting(cfgfile,(void *)&filetagnode->WarezFile,VTYPE_BOOL,optionstr,OPT_SINGLE))
  1751.           {
  1752.  
  1753.             sprintf(optionstr,"ConferenceNum_%d",N_ND->TaggedFiles);
  1754.             if (HBBS_GetSetting(cfgfile,(void *)&filetagnode->ConferenceNum,VTYPE_BIGNUM,optionstr,OPT_SINGLE))
  1755.             {
  1756.  
  1757.               sprintf(optionstr,"FileSize_%d",N_ND->TaggedFiles);
  1758.               if (HBBS_GetSetting(cfgfile,(void *)&filetagnode->FileSize,VTYPE_BIGNUM,optionstr,OPT_SINGLE))
  1759.               {
  1760.                 Error=FALSE;
  1761.                 AddTail(N_ND->TaggedFileList,(struct Node*) filetagnode);
  1762.               }
  1763.             }
  1764.           }
  1765.           if (Error)
  1766.           {
  1767.             FreeStr(strptr);
  1768.             FreeVec(filetagnode);
  1769.             N_ND->TaggedFiles--;
  1770.           }
  1771.         }
  1772.       }
  1773.     } while (Error==FALSE);
  1774.     HBBS_FlushConfig(cfgfile);
  1775.   }
  1776. }
  1777.  
  1778.  
  1779. void ResetVars( void )
  1780. {
  1781.   LONG loop;
  1782.  
  1783.   for (loop=0;loop<LEN_ACTIONS;loop++)
  1784.   {
  1785.     N_ND->Actions[loop]=ACTC_NONE;
  1786.   }
  1787.   N_ND->Actions[LEN_ACTIONS]=0;
  1788.  
  1789.   N_ND->NodeFlags=NFLG_NONE;
  1790.   N_ND->User.Valid=FALSE;
  1791.   N_ND->Action[0]=0;
  1792.   N_ND->DoorReturn[0]=0;
  1793.   N_ND->CurrentLine[0]=0;
  1794.   N_ND->CurrentLineWrap[0]=0;
  1795.   N_ND->CurrentConf=NULL;
  1796.   N_ND->MaxDIZLines=N_ND->NodeSettings.MaxDIZLines;
  1797.   N_ND->User.FilesUploaded=0L;
  1798.   N_ND->User.FilesDownloaded=0L;
  1799.   N_ND->User.BytesUploaded=0L;
  1800.   N_ND->User.BytesDownloaded=0L;
  1801.   N_ND->User.PagesMade=0L;
  1802.   N_ND->User.NukedFiles=0L;
  1803.   N_ND->User.MsgsRead=0L;
  1804.   N_ND->User.MsgsWritten=0L;
  1805.   N_ND->DoorLogOverride=FALSE;
  1806.   HBBS_SetBBSCols();
  1807. }
  1808.  
  1809. void FreeData( void )
  1810. {
  1811.   if (N_ND->User.Valid)
  1812.   {
  1813.     N_ND->User.NormalData.TimeUsed+=HBBS_TimeOnline();
  1814.     HBBS_SaveUserData(&N_ND->User.NormalData);
  1815.     SaveFileTags();
  1816.     FreeFileTags(N_ND);
  1817.   }
  1818.   N_ND->OnlineStatus=OS_OFFLINE;
  1819. }
  1820.  
  1821. void GoBBS( void )
  1822. {
  1823.   char tmpstr[1024],confstr[10],datestr[LEN_DATESTR],timestr[LEN_TIMESTR];
  1824.   V_BIGNUM confnum,loop,loop2;
  1825.   BOOL ReLogin=FALSE;
  1826.  
  1827.   do
  1828.   {
  1829.     ResetVars();
  1830.     PutText(str_CLS);
  1831.     PutText("\033[37;1m");
  1832.  
  1833.     sprintf(tmpstr,"HNode%dLoginType",N_ND->NodeNum);
  1834.  
  1835.     switch(N_ND->LoginType)
  1836.     {
  1837.       case LOGIN_LOCAL:
  1838.         ConWriteStr("-=LOCAL LOGIN=-\r\n");
  1839.         SetVar(tmpstr,"LOCAL",-1 ,GVF_GLOBAL_ONLY);
  1840.         break;
  1841.       case LOGIN_REMOTE:
  1842.         ConWriteStr("-=REMOTE LOGIN=-\r\n");
  1843.         SetVar(tmpstr,"REMOTE",-1 ,GVF_GLOBAL_ONLY);
  1844.         break;
  1845.     }
  1846.  
  1847.     sprintf(tmpstr,"************************************************[%s*", N_ND->LoginType==LOGIN_REMOTE ? "REMOTE]" : "LOCAL]*");
  1848.     HBBS_AddToCallersLog(tmpstr);
  1849.  
  1850.  
  1851.     PutText(ANSI_RESET);
  1852.  
  1853.     GoSystemDoor("FRONTEND",NULL);
  1854.     if (N_ND->OnlineStatus==OS_ONLINE)
  1855.     {
  1856.       // ok, check to see what the frontend door returned..
  1857.       strcpy(tmpstr,N_ND->DoorReturn);
  1858.  
  1859.       if (iposition("HACK",tmpstr)>=0)
  1860.       {
  1861.         sprintf(tmpstr,"Hack Attempt - %s",(N_ND->User.Valid ? N_ND->User.CallData.Handle : ""));
  1862.         HBBS_AddToCallersLog(tmpstr);
  1863.  
  1864.         // update list of PW Fails..
  1865.  
  1866.         if (N_ND->User.Valid)
  1867.         {
  1868.           Add_Last_PWFail(N_ND->User.CallData.Handle); // add to both...
  1869.           Add_Last_Caller(N_ND->User.CallData.Handle);
  1870.           N_ND->Actions[ACTN_HACK]=ACTC_HACK;
  1871.         }
  1872.  
  1873.       }
  1874.       else
  1875.       if (iposition("FAILED",tmpstr)>=0)
  1876.       {
  1877.         // do something.. (update calls log)
  1878.  
  1879.         sprintf(tmpstr,"Failed Login - %s",(N_ND->User.Valid ? N_ND->User.CallData.Handle : ""));
  1880.         HBBS_AddToCallersLog(tmpstr);
  1881.       }
  1882.       else
  1883.       if (iposition("LOGGEDIN",tmpstr)>=0)
  1884.       {
  1885.         N_ND->Actions[ACTN_CARRIERLOST]=ACTC_CARRIERLOST; // the LOGOUT door ('G') must set this to ACTC_NONE
  1886.  
  1887.         sprintf(tmpstr,"User logged in, Handle: %s Group: %s Speed: %s",N_ND->User.CallData.Handle,N_ND->User.CallData.Group,N_ND->ConnectBaud);
  1888.         HBBS_AddToCallersLog(tmpstr);
  1889.  
  1890.         HBBS_SetAccess();
  1891.  
  1892.         SetWatchTitles();
  1893.         DOOR_UpdateNodeStatus(UPD_NAME);
  1894.         DOOR_UpdateNodeStatus(UPD_GROUP);
  1895.         Add_Last_Caller(N_ND->User.CallData.Handle);
  1896.  
  1897.         HBBS_GetDate(datestr);
  1898.         HBBS_GetTime(timestr);
  1899.  
  1900.         // update the users stats..
  1901.  
  1902.         HBBS_GetDateStr(tmpstr,N_ND->User.CallData.LastCalledDate);
  1903.         if (stricmp(tmpstr,datestr)!=0) // date last user called is different from today..
  1904.         {
  1905.           N_ND->User.CallData.TimeUsed=0;
  1906.           N_ND->User.NormalData.TimeUsed=0;
  1907.         }
  1908.  
  1909.         N_ND->User.NormalData.CallsMade++;
  1910.         N_ND->User.CallData.CallsMade++;
  1911.         time(&N_ND->User.CallData.LastCalledDate);
  1912.         N_ND->User.NormalData.LastCalledDate=N_ND->User.CallData.LastCalledDate;
  1913.  
  1914.         // user logged in ok.
  1915.         sprintf(tmpstr,"HNode%dUser",N_ND->NodeNum);
  1916.         SetVar(tmpstr,N_ND->User.CallData.Handle,-1,GVF_GLOBAL_ONLY);
  1917.         LoadFileTags();
  1918.  
  1919.         if (stricmp(BBSGlobal->LastCalledDate,datestr)==0)
  1920.         {
  1921.           BBSGlobal->CallsToday++;
  1922.           N_ND->CallsToday++;
  1923.         }
  1924.         else
  1925.         {
  1926.           BBSGlobal->CallsToday=1;
  1927.           N_ND->CallsToday=1;
  1928.         }
  1929.  
  1930.         BBSGlobal->CallsEver++;
  1931.  
  1932.         strcpy(BBSGlobal->LastCalledDate,datestr);
  1933.         strcpy(BBSGlobal->LastCalledTime,timestr);
  1934.  
  1935.         strcpy(N_ND->LastCalledDate,datestr);
  1936.         strcpy(N_ND->LastCalledTime,timestr);
  1937.  
  1938.         HBBS_SaveCallsData();
  1939.         UpdatePrivateData();
  1940.  
  1941.  
  1942.         UpdateInfoWin(); // updates calls number in the window...
  1943.  
  1944.         GoSystemDoor("CheckUser","LOGON");
  1945.  
  1946.         if (stricmp(N_ND->DoorReturn,"LOGIN_DENIED")==0)
  1947.         {
  1948.         }
  1949.         else
  1950.         {
  1951.  
  1952.           sprintf(tmpstr,"Speed_%s",N_ND->ConnectBaud);
  1953.           GoSystemDoor(tmpstr,NULL);
  1954.  
  1955.           if (N_ND->OnlineStatus==OS_ONLINE)
  1956.           {
  1957.  
  1958.             if (N_ND->User.CallData.Status!=USER_NEW)
  1959.             {
  1960.               DisplaySpecialScreen("LoginLogo");
  1961.             }
  1962.  
  1963.             if (N_ND->OnlineStatus==OS_ONLINE)
  1964.             {
  1965.  
  1966.               GoUserDoor("WALL",NULL);
  1967.  
  1968.               DisplaySpecialScreen("Bulletin");
  1969.  
  1970.               // check to see if user want's to keep tagged files from last visit
  1971.               // if he left with tagged files or lost carrier with files still tagged
  1972.  
  1973.               GoSystemDoor("CHECKTAGS",NULL);
  1974.  
  1975.               GoSystemDoor("MAILSCAN",NULL);
  1976.  
  1977.  
  1978.               sprintf(tmpstr,"HBBS:Screens/Users/%s.TXT",N_ND->User.CallData.Handle);
  1979.               DisplayScreen(tmpstr);  // *C* keep ?
  1980.  
  1981.               confnum=N_ND->User.CallData.LastConf;
  1982.               if (N_ND->User.CallData.PreferedConf) confnum=N_ND->User.CallData.PreferedConf;
  1983.               sprintf(confstr,"%d",confnum);
  1984.               GoSystemDoor("JOINCONF",confstr);
  1985.  
  1986.  
  1987.               GoSystemDoor("CMDPROMPT",NULL);
  1988.  
  1989.               // Normally a user is only logged off a) by the sysop pressing F10 or b) by
  1990.               // typing G at the CMDPROMPT door which then calls the logoff door. but if
  1991.               // there is a problem with starting the CMDPROMPT door then we'll have to force
  1992.               // logout the user by trying to run the LOGOUT door, which should logoff the
  1993.               // user
  1994.  
  1995.               if (N_ND->OnlineStatus==OS_ONLINE)
  1996.               {
  1997.                 GoUserDoor("G","SYSTEM");
  1998.               }
  1999.             }
  2000.           }
  2001.  
  2002.           // do the logoff scripts, but only if a user actually logged in..
  2003.           // and unlike /X this gets called even if you do a RL
  2004.           // so all your bulletins actually get updated!
  2005.  
  2006.           sprintf(tmpstr,"execute HBBS:Scripts/LogOff%ld.script %ld %ld",N_ND->NodeNum,N_ND->NodeNum,N_ND->User.CallData.UserID);
  2007.           HBBS_RunDOSCMD(tmpstr,FALSE);
  2008.  
  2009.           sprintf(tmpstr,"execute HBBS:Scripts/LogOff_Global.script %ld %ld",N_ND->NodeNum,N_ND->User.CallData.UserID);
  2010.           HBBS_RunDOSCMD(tmpstr,FALSE);
  2011.         }
  2012.       }
  2013.     }
  2014.     strcpy(tmpstr,"Actions: ");
  2015.     loop2=strlen(tmpstr);;
  2016.     for (loop=0;loop<LEN_ACTIONS;loop++)
  2017.     {
  2018.       if (N_ND->Actions[loop]!=ACTC_NONE)
  2019.       {
  2020.         tmpstr[loop2++]=N_ND->Actions[loop];
  2021.       }
  2022.     }
  2023.     tmpstr[loop2]=0;
  2024.     HBBS_AddToCallersLog(tmpstr);
  2025.  
  2026.     sprintf(tmpstr,"Totals: FU=%d FD=%d BU=%d BD=%d PM=%d NK=%d MR=%d MW=%d",
  2027.             N_ND->User.FilesUploaded,
  2028.             N_ND->User.FilesDownloaded,
  2029.             N_ND->User.BytesUploaded,
  2030.             N_ND->User.BytesDownloaded,
  2031.             N_ND->User.PagesMade,
  2032.             N_ND->User.NukedFiles,
  2033.             N_ND->User.MsgsRead,
  2034.             N_ND->User.MsgsWritten);
  2035.     HBBS_AddToCallersLog(tmpstr);
  2036.     sprintf(tmpstr,"Time Online: %ld",HBBS_TimeOnline());
  2037.     HBBS_AddToCallersLog(tmpstr);
  2038.  
  2039.     HBBS_AddToCallersLog("End Of Session");
  2040.  
  2041.  
  2042.     FreeData();
  2043.     if (stricmp(N_ND->DoorReturn,"RELOGIN")==0)
  2044.     {
  2045.       ReLogin=TRUE;
  2046.       N_ND->OnlineStatus=OS_ONLINE;
  2047.       HBBS_AddToCallersLog("User is re-logging in!");
  2048.     }
  2049.     else
  2050.     {
  2051.       ReLogin=FALSE;
  2052.     }
  2053.  
  2054.   } while(ReLogin);
  2055.  
  2056.   HangUp();
  2057. }
  2058.  
  2059. void ResetNodeVars( void )
  2060. {
  2061.   ResetVars();
  2062.   // this is called just before the await connect door is called..
  2063.   strcpy(N_ND->ConnectBaud,"--------");
  2064.   DOOR_UpdateNodeStatus(UPD_ACTION);
  2065.   DOOR_UpdateNodeStatus(UPD_CPSBAUD);
  2066.   HBBS_SetAccess(); // clear access levels
  2067. }
  2068.  
  2069. BOOL CheckModem( void )
  2070. {
  2071.   BOOL retval=TRUE,Done=FALSE;
  2072.   if (N_ND->SerOK)
  2073.   {
  2074.     do
  2075.     {
  2076.       SerReset();
  2077.       if (SerWriteStrWithTimeout("AT\n\r",5,0))
  2078.       {
  2079.         Delay(N_ND->NodeDevice.DelayBetweenCmds);
  2080.         Done=TRUE;
  2081.       }
  2082.       else
  2083.       {
  2084.         Done=((rtEZRequest("Modem Not Responding","Retry|Cancel",NULL,(struct TagItem *)&rttags,NULL)) ? FALSE : TRUE);
  2085.         if (Done) retval=FALSE;
  2086.       }
  2087.       SerReset();
  2088.     } while (!Done);
  2089.   }
  2090.   return(retval);
  2091. }
  2092.  
  2093. void AwaitConnect( void )
  2094. {
  2095.   BOOL Error=FALSE;
  2096.  
  2097.   ResetNodeVars();
  2098.  
  2099.   if (((N_ND->NodeDevice.NullModemCable==FALSE) && CheckModem()) || (N_ND->NodeDevice.NullModemCable==TRUE))
  2100.   {
  2101.     do
  2102.     {
  2103.       if (!N_ND->NodeDevice.NullModemCable) InitModem();
  2104.       Error=!GoSystemDoor("AWAIT",NULL);                 // GoSys returns true if door loads OK
  2105.  
  2106.       // if local login then put modem offhook so no-one else calls...
  2107.       if (N_ND->LoginType==LOGIN_LOCAL)
  2108.       {
  2109.         if (!N_ND->NodeDevice.NullModemCable) OffHook();
  2110.         strcpy(N_ND->ConnectBaud,"LOCAL");
  2111.       }
  2112.  
  2113.       DOOR_UpdateNodeStatus(UPD_CPSBAUD);
  2114.       if (N_ND->LoginType!=LOGIN_NONE)
  2115.       {
  2116.         if (HistoryList=HBBS_CreateList())
  2117.         {
  2118.           HistoryItems=0;
  2119.  
  2120.           SendStatus(STAT_ONLINE);
  2121.           N_ND->OnlineStatus=OS_ONLINE;
  2122.  
  2123.           GoBBS();
  2124.  
  2125.           N_ND->LoginType=LOGIN_NONE;
  2126.  
  2127.           FreeStrList(HistoryList);
  2128.           HistoryList=NULL;
  2129.           HistoryItems=0;
  2130.  
  2131.           HBBS_FreeListNodes(N_ND->OLMList);
  2132.           N_ND->OLMCount=0;
  2133.  
  2134.           if (N_ND->NodeFlags & NFLG_OLMSWAITING) N_ND->NodeFlags-=NFLG_OLMSWAITING;
  2135.  
  2136.           SendStatus(STAT_READY);
  2137.         }
  2138.  
  2139.       }
  2140.       ResetNodeVars();
  2141.     } while (N_ND->RequestShutdown==FALSE && !Error);
  2142.     if (!N_ND->NodeDevice.NullModemCable) OffHook();
  2143.   } // else do error message
  2144.   if (Error)
  2145.   {
  2146.     HBBS_rterror("Error running door, \"Await\"");
  2147.   }
  2148. }
  2149.  
  2150. void HandleDoorIOMsg(struct DoorIOMsg *DMsg)
  2151. {
  2152.   DMsg->ReturnVal=0;
  2153.   switch(DMsg->Status)
  2154.   {
  2155.     case DOORIO_WRITECONSTR:
  2156.       ConWriteStr(DMsg->Data);
  2157.       break;
  2158.     case DOORIO_WRITECONDATA:
  2159.       ConWriteData(DMsg->Data,DMsg->DataLength);
  2160.       break;
  2161.     case DOORIO_WRITESERSTR:
  2162.       SerWriteStr(DMsg->Data);
  2163.       break;
  2164.     case DOORIO_WRITESERDATA:
  2165.       SerWriteData(DMsg->Data,DMsg->DataLength);
  2166.       break;
  2167.     case DOORIO_WRITESTR:
  2168.       PutText(DMsg->Data);
  2169.       break;
  2170.     case DOORIO_GETLINE:
  2171.       DMsg->ReturnVal=Get_Line(DMsg->Flags,DMsg->Data[0],DMsg->Num1,DMsg->Num2,DMsg->OptionStr);
  2172.       break;
  2173.     case DOORIO_SYSTEMDOOR:
  2174.       DMsg->ReturnVal=GoSystemDoor(DMsg->Data,DMsg->OptionStr);
  2175.       break;
  2176.     case DOORIO_USERDOOR:
  2177.       DMsg->ReturnVal=GoUserDoor(DMsg->Data,DMsg->OptionStr);
  2178.       break;
  2179.     case DOORIO_HANGUP:
  2180.       HangUp();
  2181.       break;
  2182.     case DOORIO_DISPLAYSCREEN:
  2183.       DMsg->ReturnVal=DisplayScreen(DMsg->Data);
  2184.       break;
  2185.     case DOORIO_DISPLAYSPECIALSCREEN:
  2186.       DMsg->ReturnVal=DisplaySpecialScreen(DMsg->Data);
  2187.       break;
  2188.     case DOORIO_PAUSEPROMPT:
  2189.       PausePrompt(DMsg->Data,0);
  2190.       break;
  2191.     case DOORIO_CONTINUEPROMPT:
  2192.       DMsg->ReturnVal=ContinuePrompt(DMsg->Data,DMsg->Flags);
  2193.       break;
  2194.     case DOORIO_ADDLASTUPLOAD:
  2195.       Add_Last_Upload(DMsg->Data);
  2196.       break;
  2197.     case DOORIO_MENUPROMPT:
  2198.       MenuPrompt(DMsg->Data,DMsg->OptionStr[0]);
  2199.       break;
  2200.     case DOORIO_CHECKRAW:
  2201.       DMsg->ReturnVal=CheckRaw(DMsg->Flags);
  2202.       break;
  2203.   }
  2204.   // a door message MAY be sent to the node without the control or other program
  2205.   // wanting to be told that the NODE has recived the message, all messages sent
  2206.   // that DONT want a reply WILL be freed..
  2207.  
  2208.   if (DMsg->message.mn_ReplyPort)
  2209.   {
  2210.     ReplyMsg((struct Message *)DMsg);
  2211.   }
  2212.   else
  2213.   {
  2214.     FreeVec(DMsg);
  2215.   }
  2216. }
  2217.  
  2218.